package com.quectel.taskserver.job.patrol;

import cn.hutool.core.lang.func.LambdaUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.quectel.constant.core.devicepatrol.DevicePatrolEventReportConstants;
import com.quectel.constant.core.devicepatrol.DevicePatrolTaskConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.core.module.devicepatrol.dto.DevicePatrolEventReportDto;
import com.quectel.core.module.devicepatrol.dto.DevicePatrolTaskDto;
import com.quectel.core.module.devicepatrol.service.DevicePatrolEventReportService;
import com.quectel.core.module.devicepatrol.service.DevicePatrolTaskService;
import com.quectel.util.common.DateUtils;
import com.quectel.util.common.JacksonUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.shardingsphere.elasticjob.api.ShardingContext;
import org.apache.shardingsphere.elasticjob.simple.job.SimpleJob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 每天检查之前所有的巡检上报 如果有未完成的需要将任务标记 每天 00:00执行
 *
 * @author zhangheng
 * @email nolan.zhang@quectel.com
 * @date 2022/6/8 17:27 下午
 */
@Component
public class DevicePatrolMissedDetectionTask implements SimpleJob {

    private static final Logger LOGGER = LoggerFactory.getLogger(DevicePatrolMissedDetectionTask.class);

    @DubboReference
    private DevicePatrolTaskService devicePatrolTaskService;
    @DubboReference
    private DevicePatrolEventReportService devicePatrolEventReportService;

    @Override
    public void execute(ShardingContext shardingContext) {
        String todayStr = DateUtils.format(new Date(), DateUtils.FormatType.COMMON);
        LOGGER.info(String.format("设备巡检任务漏检检查{%s}start", todayStr));


        List<DevicePatrolTaskDto> result = new ArrayList<>();
        int pageNo = 1;
        while (true) {
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put(DevicePatrolTaskConstants.EXEC_END_TIME_END, todayStr);
            List<Byte> statuses = new ArrayList<>();
            statuses.add(DevicePatrolTaskConstants.TasksStatusEnum.STATUS_UNEXECUTED.getStatus());
            statuses.add(DevicePatrolTaskConstants.TasksStatusEnum.STATUS_EXECUTING.getStatus());
            queryMap.put(SystemConstants.STATUSES, statuses);
            queryMap.put("offset", (pageNo - 1) * 2000);
            queryMap.put("limit", 2000);
            List<DevicePatrolTaskDto> list = devicePatrolTaskService.queryList(queryMap);
            if (list.size() <= 0) {
                break;
            }
            result.addAll(list);
            pageNo++;
        }

        //将执行数量不是最大数量的task全部改为漏检

        for (DevicePatrolTaskDto devicePatrolTaskDto : result) {
            if (devicePatrolTaskDto.getExecCount() != null && devicePatrolTaskDto.getExecCount() < devicePatrolTaskDto.getRouteCount()) {
                devicePatrolTaskDto.setExecStatus(DevicePatrolTaskConstants.TasksStatusEnum.STATUS_MISSED_DETECTION.getStatus());

                Set<Byte> routeExecTotalStatus = JacksonUtils.parse(devicePatrolTaskDto.getRouteExecTotalStatus(), new TypeReference<Set<Byte>>() {
                });
                routeExecTotalStatus.add(DevicePatrolTaskConstants.TasksStatusEnum.STATUS_MISSED_DETECTION.getStatus());
                devicePatrolTaskDto.setRouteExecTotalStatus(JacksonUtils.toJsonString(routeExecTotalStatus));

                devicePatrolTaskService.updateById(devicePatrolTaskDto);

                //查询所有的上报详情标记为漏检
                Map<String, Object> queryMap = new HashMap<>(2);
                queryMap.put(LambdaUtil.getFieldName(DevicePatrolEventReportDto::getTaskId), devicePatrolTaskDto.getId());
                queryMap.put(LambdaUtil.getFieldName(DevicePatrolEventReportDto::getStatus), DevicePatrolEventReportConstants.ReportStatusEnum.STATUS_UNEXECUTED.getStatus());
                List<DevicePatrolEventReportDto> patrolEventReportDtos = devicePatrolEventReportService.queryList(queryMap);
                if (CollectionUtils.isNotEmpty(patrolEventReportDtos)) {
                    for (DevicePatrolEventReportDto reportDto : patrolEventReportDtos) {
                        reportDto.setStatus(DevicePatrolEventReportConstants.ReportStatusEnum.STATUS_MISSED_DETECTION.getStatus());
                        devicePatrolEventReportService.updateById(reportDto);
                    }

                }

            }
        }

        LOGGER.info(String.format("设备巡检任务漏检检查{%s}end", todayStr));
    }
}
